﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using PowerPoint = Microsoft.Office.Interop.PowerPoint;
using Office = Microsoft.Office.Core;
using System.Collections.ObjectModel;
using ThreeByte.ActiveDeck.Config;
using System.ComponentModel;
using ThreeByte.ActiveDeck.Content;
using log4net;
using ThreeByte.ActiveDeck.Data;
using ThreeByte.ActiveDeck.Service;
using System.Xml.Linq;
using ThreeByte.ActiveDeck.Controls;

namespace ThreeByte.ActiveDeck.AddIn.Controls.Wizard.Pages
{
    /// <summary>
    /// Interaction logic for PublishPage.xaml
    /// </summary>
    public partial class PublishPage : Page, INotifyPropertyChanged
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(PublishPage));
        private readonly CoreConfig Config;

        public PublishPage() {
            InitializeComponent();

            Config = WizardMainFrame.ActiveConfig;

            //Populate fields with existing info
            InitFields(Config);
        }

        private void InitFields(CoreConfig config) {
            UserAccessComboBox.SelectedIndex = (int)config.UserAccess;
            if(config.HasPresenterLogin) {
                PresenterEmail.Text = config.PresenterLogin.UserName;
                PresenterPasswordTextBox.Password = config.PresenterLogin.Password;
            }
            if(config.HasPresentationID) {
                PresentationNameText.Text = config.Name;
                PresentationIDText.Text = config.ID;
            }
            ValidatePage();
        }

        private void ValidatePage() {
            bool hasCredentials = (!(string.IsNullOrWhiteSpace(PresenterEmail.Text))
                                && !(string.IsNullOrWhiteSpace(PresenterPasswordTextBox.Password)));
            bool hasPresName = !(string.IsNullOrWhiteSpace(PresentationNameText.Text));

            PublishButton.IsEnabled = false;
            GetIDButton.IsEnabled = false;
            if(Config.HasPresentationID){
                PresentationNameText.IsEnabled = false;
                if(hasCredentials) {
                    PublishButton.IsEnabled = true;
                }
            } else {
                PresentationNameText.IsEnabled = true;
                if(hasPresName && hasCredentials) {
                    GetIDButton.IsEnabled = true;
                }
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName) {
            if(PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }


        private void CannotExecute(object sender, CanExecuteRoutedEventArgs e) {
            e.CanExecute = false;
            e.Handled = true;
        }

        private void HelpExecuted(object sender, ExecutedRoutedEventArgs e) {

        }

        private void PublishButton_Click(object sender, RoutedEventArgs e) {
            ErrorText.Visibility = Visibility.Collapsed;
            Config.UserAccess = (UserAccess)(UserAccessComboBox.SelectedIndex);

            //TODO:Is there a better way to do this?
            //Check to see if there are any user slides to publish.
            bool containsSlides = false;
            foreach(SlideConfig s in Config.Slides) {
                containsSlides = true;
                break;
            }
            if(!containsSlides) {
                MessageBox.Show("This presentation does not contain any configured activities, yet.  Please go back to the other sections and create some interative content before publishing.", "Empty Presentation");
                return;
            }

            //Open UI Dialog with progress bar
            PublishForm publishDialog = new PublishForm(Config);
            publishDialog.ShowDialog();

            if(publishDialog.ErrorMessage == null) {
                //Success
                log.Debug("Publish completed successfully");
                //Continue to the summary page
                NavigationService navService = this.NavigationService;
                if(navService != null) {
                    navService.Navigate(new SummaryPage());
                }

            } else {
                //Error
                ErrorText.Text = publishDialog.ErrorMessage;
                ErrorText.Visibility = Visibility.Visible;
            }
        }

        private void GetIDButton_Click(object sender, RoutedEventArgs e) {
            //Put up dialog
            ErrorText.Visibility = Visibility.Collapsed;
            WebserviceDialog.Visibility = Visibility.Visible;

            //Make the background call
            PresentationInfo pInfo = new PresentationInfo(PresenterEmail.Text, PresenterPasswordTextBox.Password, PresentationNameText.Text);
            System.Threading.ThreadPool.QueueUserWorkItem(GetPresentationID, pInfo);

        }


        private void GetPresentationID(object state) {
            PresentationInfo pInfo = (PresentationInfo)state;
            WebServiceClient client = new WebServiceClient(new System.Net.NetworkCredential(pInfo.UserName, pInfo.Password));
            XElement response = null;

            try {

                response = client.NewPresentation(pInfo.PresentationName);

                PresentationHeader newPres = new PresentationHeader(response);

                //Exit with success
                Dispatcher.BeginInvoke((Action)delegate() {
                    //Close the dialog
                    log.Debug("Presentation ID configured successfully");
                    CompletionText.Visibility = Visibility.Visible;
                    System.Threading.Thread.Sleep(1000);
                    WebserviceDialog.Visibility = Visibility.Collapsed;

                    //Commit the pres info updates
                    PresentationIDText.Text = newPres.ID;
                    Config.ID = newPres.ID;
                    Config.Name = newPres.Name;
                    //Commit the new credentials
                    Config.PresenterLogin.UserName = pInfo.UserName;
                    Config.PresenterLogin.Password = pInfo.Password;
                    Config.MarkAsDirty();

                    ValidatePage();
                }, null);

            } catch(Exception ex) {
                string message = "An unexpected error occured.  Please try again.";
                if(response != null && response.Name == "Error") {
                    string domain = response.Attribute("Domain").Value;
                    message = response.Attribute("Message").Value;
                }
                log.Error("Error creating presentation", ex);
                //Exit with Error
                Dispatcher.BeginInvoke((Action)delegate() {
                    //Close the dialog
                    WebserviceDialog.Visibility = Visibility.Collapsed;
                    ErrorText.Text = message;
                    ErrorText.Visibility = Visibility.Visible;
                }, null);

            }



        }


        private void PresenterPasswordTextBox_PasswordChanged(object sender, RoutedEventArgs e) {
            ValidatePage();
        }


        private class PresentationInfo
        {
            public string UserName{ get; private set;}
            public string Password { get; private set; }
            public string PresentationName { get; private set; }

            public PresentationInfo(string userName, string password, string presName) {
                UserName = userName;
                Password = password;
                PresentationName = presName;
            }
        }

        private void CheckPageValid(object sender, TextChangedEventArgs e) {
            ValidatePage();
        }

       
    }
}
